#include "gtkstylecontext.h"
#include "gtktypebuiltins.h"
#include "gtkstack.h"
-#include "gtkpopover.h"
+#include "gtkpopovermenuprivate.h"
#include "gtkintl.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsstypesprivate.h"
#include "gtksizegroup.h"
#include "gtkaccellabelprivate.h"
#include "gtkactionable.h"
+#include "gtkeventcontrollermotion.h"
+#include "gtkeventcontrollerkey.h"
/**
* SECTION:gtkmodelbutton
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("modelbutton"));
}
+static void
+enter_cb (GtkEventController *controller,
+ double x,
+ double y,
+ GdkCrossingMode mode,
+ GdkNotifyType type,
+ gpointer data)
+{
+ GtkWidget *target;
+ GtkWidget *popover;
+ gboolean is;
+ gboolean contains;
+
+ target = gtk_event_controller_get_widget (controller);
+ popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
+
+ g_object_get (controller,
+ "is-pointer-focus", &is,
+ "contains-pointer-focus", &contains,
+ NULL);
+
+ if (popover && (is || contains))
+ gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
+}
+
+static void
+leave_cb (GtkEventController *controller,
+ GdkCrossingMode mode,
+ GdkNotifyType type,
+ gpointer data)
+{
+ GtkWidget *target;
+ GtkWidget *popover;
+ gboolean is;
+ gboolean contains;
+
+ target = gtk_event_controller_get_widget (controller);
+ popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
+
+ g_object_get (controller,
+ "is-pointer-focus", &is,
+ "contains-pointer-focus", &contains,
+ NULL);
+
+ if (popover && !(is || contains))
+ gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), NULL);
+}
+
+static void
+focus_in_cb (GtkEventController *controller,
+ GdkCrossingMode mode,
+ GdkNotifyType type,
+ gpointer data)
+{
+ GtkWidget *target;
+ GtkWidget *popover;
+
+ target = gtk_event_controller_get_widget (controller);
+ popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
+
+ if (popover)
+ gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
+}
+
static void
gtk_model_button_init (GtkModelButton *button)
{
+ GtkEventController *controller;
+
button->role = GTK_BUTTON_ROLE_NORMAL;
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
button->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_hide (button->start_indicator);
gtk_widget_hide (button->end_indicator);
update_node_ordering (button);
+
+ controller = gtk_event_controller_motion_new ();
+ g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), NULL);
+ g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (button), controller);
+
+ controller = gtk_event_controller_key_new ();
+ g_signal_connect (controller, "focus-in", G_CALLBACK (focus_in_cb), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (button), controller);
}
/**
#include "config.h"
#include "gtkpopovermenu.h"
+#include "gtkpopovermenuprivate.h"
+
#include "gtkstack.h"
#include "gtkstylecontext.h"
#include "gtkintl.h"
struct _GtkPopoverMenu
{
GtkPopover parent_instance;
+
+ GtkWidget *active_item;
};
struct _GtkPopoverMenuClass
G_DEFINE_TYPE (GtkPopoverMenu, gtk_popover_menu, GTK_TYPE_POPOVER)
+void
+gtk_popover_menu_set_active_item (GtkPopoverMenu *menu,
+ GtkWidget *item)
+{
+ if (menu->active_item != item)
+ {
+ if (menu->active_item)
+ gtk_widget_unset_state_flags (menu->active_item, GTK_STATE_FLAG_SELECTED);
+
+ menu->active_item = item;
+
+ if (menu->active_item)
+ {
+ gtk_widget_set_state_flags (menu->active_item, GTK_STATE_FLAG_SELECTED, FALSE);
+ gtk_widget_grab_focus (menu->active_item);
+ }
+ }
+}
+
static void
visible_submenu_changed (GObject *object,
GParamSpec *pspec,
--- /dev/null
+/* GTK - The GIMP Toolkit
+ * Copyright © 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_POPOVER_MENU_PRIVATE_H__
+#define __GTK_POPOVER_MENU_PRIVATE_H__
+
+#include "gtkpopovermenu.h"
+
+G_BEGIN_DECLS
+
+void gtk_popover_menu_set_active_item (GtkPopoverMenu *popover,
+ GtkWidget *item);
+
+G_END_DECLS
+
+#endif /* __GTK_POPOVER_PRIVATE_H__ */